#include "Transformation.h"
#include <math.h>

void Transformation::apply(const Matrix4& matrix, Vector& v )
{
	float vin[4] = { v.x, v.y, v.z, 1 };

	float v0 = matrix.data[0][0]*vin[0] + matrix.data[0][1]*vin[1] + 
		matrix.data[0][2]*vin[2] + matrix.data[0][3]*vin[3];
	float v1 = matrix.data[1][0]*vin[0] + matrix.data[1][1]*vin[1] +
		matrix.data[1][2]*vin[2] + matrix.data[1][3]*vin[3];
	float v2 = matrix.data[2][0]*vin[0] + matrix.data[2][1]*vin[1] +
		matrix.data[2][2]*vin[2] + matrix.data[2][3]*vin[3];
	float v3 = matrix.data[3][0]*vin[0] + matrix.data[3][1]*vin[1] + 
		matrix.data[3][2]*vin[2] + matrix.data[3][3]*vin[3];

	v = Vector(v0/v3,v1/v3,v2/v3);
}

void Transformation::apply(const Matrix4& matrix, std::vector<Vector>& list )
{
	for( int i = 0; i < list.size(); i++ )
	{
		apply( matrix, list[i] );
	}
}

Matrix4 Transformation::getRotationMatrix( const Vector& rotation )
{
	float cosX = cos2(rotation.x);
	float cosY = cos2(rotation.y);
	float cosZ = cos2(rotation.z);

	float sinX = sin2(rotation.x);
	float sinY = sin2(rotation.y);
	float sinZ = sin2(rotation.z);

	float m[4][4] = {
		{
			cosX*cosY,
			-cosX*sinY*sinZ-sinX*cosZ,
			cosX*sinY*cosZ-sinX*sinZ,
			0
		},
		{
			sinX*cosY,
			sinX*sinY*sinZ+cosX*cosZ,
			sinX*sinY*cosZ+cosX*sinZ,
			0
		},
		{
			-sinY,
			-cosY*sinZ,
			cosY*cosZ,
			0
		},
		{
			0,
			0,
			0,
			1
		}
	};

	return Matrix4(m);
}

Matrix4 Transformation::getTranslationMatrix( const Vector& move )
{
	float m[4][4] = 
	{
		{1, 0, 0, move.x},
		{0, 1, 0, move.y},
		{0, 0, 1, move.z},
		{0, 0, 0, 1}
	};

	return Matrix4(m);
}

Matrix4 Transformation::getScaleMatrix( float scale )
{
	float m[4][4] = 
	{
		{scale, 0, 0, 0},
		{0, scale, 0, 0},
		{0, 0, scale, 0},
		{0, 0, 0, 1}
	};

	return Matrix4(m);
}